package com.phone580.app.service;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;

import com.phone580.app.CommonData;
import com.phone580.app.Constant;
import com.phone580.app.R;
import com.phone580.app.dao.DownloadInfoDao;
import com.phone580.app.entity.DownloadInfoEntity;
import com.phone580.app.model.DownloadManagerModel;
import com.phone580.app.untilty.CommonUtility;

public class DownloadService extends Service {
	private static Map<Long, Thread> task = Collections.synchronizedMap(new LinkedHashMap<Long, Thread>());
	private DownloadBinder binder = new DownloadBinder();
	private static int notifyID = 0;
	private static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
			2, 3, 3, TimeUnit.SECONDS,
			new ArrayBlockingQueue<Runnable>(100),
			new ThreadPoolExecutor.DiscardOldestPolicy());
	
	@Override
	public IBinder onBind(Intent intent) {
		return binder;
	}
	
	@Override
	public void onCreate() {
		super.onCreate();
	}

	@Override
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		return super.onStartCommand(intent, flags, startId);
	}

	class DownloadBinder extends Binder implements DownloadCallback {

		@Override
		public void startDownload(DownloadInfoEntity entity) {
//			DownloadTask dt = new DownloadTask(entity);
//			task.put(entity.getId(), dt);
//			dt.start();
			FutureTask<Object> future = new FutureTask<Object>(new DownloadTask(entity), null);
			threadPool.execute(future);
		}

		@Override
		public void pauseDownload(DownloadInfoEntity entity) {
			if (task.get(entity.getId()) != null) {
				((DownloadTask)task.get(entity.getId())).pause();
			}
		}

		@Override
		public void cancelDownload(DownloadInfoEntity entity) {
			if (task.get(entity.getId()) != null) {
				((DownloadTask)task.get(entity.getId())).cancel();
			} else {
				DownloadManagerModel model = new DownloadManagerModel(DownloadService.this);
				model.remove(entity.getId());
				//删除文件
				File temp = new File(entity.getFilePath());
				if (temp.exists()) {
					temp.delete();
				}
			}
		}

		@Override
		public boolean isDownloading(long id) {
			return task.containsKey(id);
		}

		@Override
		public void networkSettingChange() {
			if (CommonData.ONLY_WIFI) {
				if (!CommonUtility.isWiFiActive(DownloadService.this)) {
					for (Entry<Long, Thread> entry: task.entrySet()) {
						((DownloadTask)entry.getValue()).pause();
					}
				}
			}
		}
		
		
	}

	class DownloadTask extends Thread {

		private URL httpurl;
		private HttpURLConnection connection;
		private DownloadInfoEntity entity;
		private RandomAccessFile randomAccessFile;
		private InputStream in;
		private DownloadManagerModel model;
		private Object lock = new Object();
		private boolean done = false;
		
		public DownloadTask(DownloadInfoEntity entity) {
			this.entity = entity;
			model = new DownloadManagerModel(DownloadService.this);
			try {
				httpurl = new URL(entity.getUrl());
				connection = (HttpURLConnection) httpurl.openConnection();
				connection.setConnectTimeout(5000);
				connection.setRequestMethod("GET");
				if (entity.getFileSize() != 0) {
					// 设置范围，格式为Range：bytes x-y;
//					connection.setRequestProperty(
//							"Range",
//							"bytes=" + entity.getCompleteSize() + "-"
//									+ entity.getFileSize());
					connection.setRequestProperty(
							"Range",
							"bytes=" + entity.getCompleteSize());
				}
				randomAccessFile = new RandomAccessFile(entity.getFilePath(),
						"rwd");
				randomAccessFile.seek(entity.getCompleteSize());
			} catch (MalformedURLException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		public void cancel() {
			this.interrupt();
			//删除数据库记录
			model.remove(entity.getId());
			//删除下载队列
			task.remove(entity.getId());
			//删除文件
			File temp = new File(entity.getFilePath());
			if (temp.exists()) {
				temp.delete();
			}
		}
		
		public void pause() {
			this.interrupt();
		}

		@Override
		public void run() {
			if (CommonData.ONLY_WIFI && !CommonUtility.isWiFiActive(DownloadService.this)) {
				task.remove(entity.getId());
				return;
			}
			DownloadProcess dp = new DownloadProcess();
			synchronized (lock) {
				dp.start();
				while (!done) {
					try {
						lock.wait();
						//完成下载,从队列中删除任务
						task.remove(entity.getId());
					} catch (InterruptedException e) {
						//停止或删除操作引发异常，删除任务队列
						task.remove(entity.getId());
						done = true;
						try {
							connection.disconnect();
							randomAccessFile.close();
							if (in != null) {
								in.close();
							}
						} catch (IOException ioe) {
							ioe.printStackTrace();
						}
					}
				}
			}
		}

		class DownloadProcess extends Thread {

			@Override
			public void run() {
				try {
					if (!done) {
						if (entity.getFileSize() == 0) {
							int size = connection.getContentLength();
//							model.updateFileSize(entity.getId(), size);
							entity.setFileSize(size);
						}
						in = connection.getInputStream();
					} else {
						return;
					}
					
					byte[] buffer = new byte[4096];
					int length = -1;
					while ((length = in.read(buffer)) != -1) {
						if (length == 0) {
							continue;
						}
						randomAccessFile.write(buffer, 0, length);
						model.updateCompleteSize(entity.getId(), entity.getCompleteSize() + length);
						entity.setCompleteSize(entity.getCompleteSize() + length);
//						System.out.println("id=" + getId()
//								+ "----------filesize=" + entity.getFileSize()
//								+ "---------" + "completesize="
//								+ entity.getCompleteSize());
					}
					model.updateStatus(entity);
					showNotification();
				} catch (IOException e) {
					e.printStackTrace();
					done = true;
				}
				synchronized (lock) {
					System.out.println("notify threadid:" + getId());
					lock.notify();
				}
			}

		}
		
		
		private void showNotification() {
			if (!CommonData.Notification) {
				return;
			}
			Intent intent = new Intent();
			intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			intent.setAction(android.content.Intent.ACTION_VIEW);
			String type = "application/vnd.android.package-archive";
			intent.setDataAndType(Uri.fromFile(new File(entity.getFilePath())),
					type);
			NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
			PendingIntent contentIntent = PendingIntent.getActivity(
					DownloadService.this, 0, intent, 0);
			Notification notif = new Notification(R.drawable.phone580_icon_small,
					entity.getFileName(), 2000);
			notif.flags |= Notification.FLAG_AUTO_CANCEL;
			notif.setLatestEventInfo(DownloadService.this, "下载完成",
					entity.getFileName(), contentIntent);
			int id = notifyID++;
			nm.notify(id, notif);
			CommonData.notificationId.put(entity.getFileName(), id);
		}
	}

}
